/*
 * Copyright 2009 BioTeam Inc
 * 
 * Licensed under License GNU LESSER GENERAL PUBLIC LICENSE version 3.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.gnu.org/copyleft/lesser.html
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package net.bioteam.appweb.gwt.apps.client.qstat;

import java.util.List;

import net.bioteam.appweb.gwt.apps.client.StaticHolder;
import net.bioteam.appweb.gwt.apps.client.Util.ApplicationCallBack;
import net.bioteam.appweb.gwt.apps.clientandserver.qstat.QstatProxy;
import net.bioteam.appweb.gwt.apps.clientandserver.qstat.QstatProxyAsync;
import net.bioteam.appweb.gwt.apps.clientandserver.user.UserAction;
import net.bioteam.appweb.qstat.Job;
import net.bioteam.appweb.qstat.Qstat;
import net.bioteam.appweb.qstat.Queue;

import com.google.gwt.core.client.GWT;
import com.google.gwt.user.client.History;
import com.google.gwt.user.client.Timer;
import com.smartgwt.client.types.Alignment;
import com.smartgwt.client.types.Overflow;
import com.smartgwt.client.types.VisibilityMode;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.Canvas;
import com.smartgwt.client.widgets.HTMLPane;
import com.smartgwt.client.widgets.ImgButton;
import com.smartgwt.client.widgets.Label;
import com.smartgwt.client.widgets.Window;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.ClickHandler;
import com.smartgwt.client.widgets.events.CloseClickHandler;
import com.smartgwt.client.widgets.events.CloseClientEvent;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.CellClickEvent;
import com.smartgwt.client.widgets.grid.events.CellClickHandler;
import com.smartgwt.client.widgets.layout.LayoutSpacer;
import com.smartgwt.client.widgets.layout.SectionStack;
import com.smartgwt.client.widgets.layout.SectionStackSection;
import com.smartgwt.client.widgets.layout.VStack;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripSeparator;

public class Sgeqstat extends SectionStack
{

	public static final int WIDTH = 600;
	public VStack stack;

	public Canvas contentCanvas;
	Timer timer;

	public Sgeqstat()
	{
		setWidth(WIDTH);
		setHeight100();

		VStack headerStack = initHeader();
		headerStack.setHeight(40);
		// headerStack.setBackgroundColor("red");

		ImgButton refresh = new ImgButton();
		refresh.setSrc("[SKIN]actions/refresh.png");
		refresh.setSize(16);
		refresh.setShowFocused(false);
		refresh.setShowRollOver(false);
		refresh.setShowDown(false);
		refresh.setPrompt("reload");
		refresh.addClickHandler(new ClickHandler()
		{

			public void onClick(ClickEvent event)
			{
				reload();
			}
		});

		contentCanvas = new Canvas();
		// contentCanvas.setBackgroundColor("yellow");

		SectionStackSection section1 = new SectionStackSection();
		section1.setTitle("SGE queue status");
		section1.setItems(headerStack, contentCanvas);
		section1.setControls(refresh);
		section1.setExpanded(true);
		section1.setCanCollapse(false);

		setSections(section1);
		setVisibilityMode(VisibilityMode.MULTIPLE);
		setAnimateSections(true);

		timer = new Timer()
		{

			@Override
			public void run()
			{
				if (contentCanvas.isVisible())
				{
					Sgeqstat.this.reload();
				}

			}
		};
		// run every 20 seconds
		timer.scheduleRepeating(20000);
	}

	public VStack initHeader()
	{

		ToolStrip strip1 = new ToolStrip();
		strip1.setHeight(20);
		strip1.setWidth(WIDTH);
		strip1.setShowEdges(false);

		Label qName = new Label("Queue Name");
		qName.setWidth(185);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip1.addMember(qName);

		ToolStripSeparator stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip1.addMember(stripSeparator);

		qName = new Label("Type");
		qName.setWidth(80);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip1.addMember(qName);

		stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip1.addMember(stripSeparator);

		qName = new Label("Used/Resv/Total");
		qName.setWidth(70);
		qName.setHeight(20);
		qName.setWrap(true);
		qName.setAlign(Alignment.CENTER);
		strip1.addMember(qName);

		stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip1.addMember(stripSeparator);

		qName = new Label("Arch");
		qName.setWidth(102);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip1.addMember(qName);

		stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip1.addMember(stripSeparator);

		qName = new Label("state");
		qName.setWidth(60);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip1.addMember(qName);

		// -----------strip2
		ToolStrip strip2 = new ToolStrip();
		strip2.setHeight(20);
		strip2.setWidth(WIDTH);
		strip2.setShowEdges(false);

		qName = new Label("Job #");
		qName.setWidth(45);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip2.addMember(qName);

		stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip2.addMember(stripSeparator);

		qName = new Label("Priority");
		qName.setWidth(65);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip2.addMember(qName);

		stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip2.addMember(stripSeparator);

		qName = new Label("Name");
		qName.setWidth(60);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip2.addMember(qName);

		stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip2.addMember(stripSeparator);

		qName = new Label("owner");
		qName.setWidth(80);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip2.addMember(qName);

		stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip2.addMember(stripSeparator);

		qName = new Label("slots(Tasks #)");
		qName.setWidth(63);
		qName.setHeight(20);
		qName.setWrap(true);
		qName.setAlign(Alignment.CENTER);
		strip2.addMember(qName);

		stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip2.addMember(stripSeparator);

		qName = new Label("StartTime");
		qName.setWidth(143);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip2.addMember(qName);

		stripSeparator = new ToolStripSeparator();
		stripSeparator.setHeight(8);
		strip2.addMember(stripSeparator);

		qName = new Label("state");
		qName.setWidth(60);
		qName.setHeight(20);
		qName.setAlign(Alignment.CENTER);
		strip2.addMember(qName);

		VStack headerStack = new VStack();
		headerStack.addMember(strip1);
		headerStack.addMember(strip2);

		return headerStack;

	}

	public void init(Qstat qstat)
	{
		if (stack != null)
		{
			contentCanvas.removeChild(stack);
			stack.destroy();
		}
		stack = new VStack();
		for (Queue q : qstat.getQueueInfo().getQueues())
		{
			stack.addMember(getQueueGrid(q));
			if (!q.getJob_List().isEmpty())
				stack.addMember(getJobGrid(q.getJob_List()));
		}
		LayoutSpacer spacer = new LayoutSpacer();
		spacer.setWidth(WIDTH);
		spacer.setHeight(30);
		stack.addMember(spacer);

		Label label = new Label("<b> PENDING JOB</b>");
		label.setWidth(WIDTH);
		label.setHeight(20);
		label.setAlign(Alignment.CENTER);
		stack.addMember(label);
		if (!qstat.getPendingJobInfo().getJobs().isEmpty())
			stack.addMember(getJobGrid(qstat.getPendingJobInfo().getJobs()));

		contentCanvas.addChild(stack);

	}

	public ListGrid getJobGrid(List<Job> jobs)
	{
		ListGrid g = new ListGrid();
		g.setWidth(WIDTH);
		// setHeight100();
		// g.setAutoFitData(Autofit.VERTICAL);
		g.setAlternateRecordStyles(true);
		g.setShowAllRecords(true);
		g.setShowHeader(false);
		g.setCellHeight(20);
		g.setOverflow(Overflow.HIDDEN);

		ListGridField numberField = new ListGridField("number", "number", 50);
		numberField.setAlign(Alignment.RIGHT);
		numberField.setBaseStyle("fakelink");

		ListGridField slotsField = new ListGridField("slots", "slots", 70);
		slotsField.setAlign(Alignment.RIGHT);

		g.setFields(numberField, new ListGridField("prio", "priority", 70), new ListGridField("name", "name", 70), new ListGridField("owner", "owner", 90), slotsField, new ListGridField("start_time",
				"starttime", 150), new ListGridField("state", "state", 60));

		ListGridRecord rs[] = new ListGridRecord[jobs.size()];
		for (int i = 0; i < jobs.size(); i++)
		{
			Job job = jobs.get(i);
			ListGridRecord record = new ListGridRecord();
			record.setAttribute("name", job.getJB_Name());
			record.setAttribute("number", job.getJB_Job_Number());
			record.setAttribute("state", job.getState());
			record.setAttribute("start_time", job.getJAT_Start_Time());
			if (job.getTasks() != null && job.getTasks().length() > 0)
			{
				record.setAttribute("slots", job.getSlots()+"("+job.getTasks()+")"); 
			} else
			{
				record.setAttribute("slots", job.getSlots());
			}
			record.setAttribute("prio", String.valueOf(job.getJAT_Prio()));
			record.setAttribute("owner", job.getJB_Owner());
			rs[i] = record;
		}
		g.setHeight(rs.length * 20 + 10);

		g.setData(rs);
		g.addCellClickHandler(new CellClickHandler()
		{
			public void onCellClick(CellClickEvent event)
			{

				ListGridRecord record =  event.getRecord();
				int colNum = event.getColNum();
				if (colNum==0)
				{
					showJob(record.getAttributeAsString("number"));
				}
			}
		});
		return g;
	}

	public void showJob(final String id)
	{
		ApplicationCallBack<String> callback = new ApplicationCallBack<String>()
		{

			public void onFailureAfter(Throwable caught)
			{
				SC.warn(caught.getMessage(), StaticHolder.dumpB);
			}

			public void onSuccessAfter(String result)
			{
				final Window win = new Window();
				win.setWidth(600);
				win.setHeight(500);
				win.setTitle("job detail");
				win.setShowMinimizeButton(false);
				win.setIsModal(true);
				win.centerInPage();
				// win.setAutoSize(true);
				win.setShowCloseButton(true);
				win.addCloseClickHandler(new CloseClickHandler()
				{

					public void onCloseClick(CloseClientEvent event)
					{
						// win.hide();
						win.destroy();
					}
				});
				HTMLPane panel = new HTMLPane();
				panel.setContents(result.replaceAll("\n", "<br><br>"));
				panel.setOverflow(Overflow.AUTO);
				panel.setHeight100();
				panel.setWidth100();
				win.addItem(panel);
				win.show();
			}

			public void execute()
			{
				QstatProxyAsync proxy = (QstatProxyAsync) GWT.create(QstatProxy.class);
				proxy.getJobQstat(id, this);
			}

		};
		callback.execute();
	}

	public ListGrid getQueueGrid(Queue queue)
	{

		ListGrid g = new ListGrid();
		g.setWidth(WIDTH + 2);
		g.setCellHeight(20);
		g.setHeight(27);
		g.setBorder("2px solid purple");
		g.setShowAllRecords(true);
		g.setShowHeader(false);
		// g.setShowEdges(true);

		ListGridField archField = new ListGridField("arch", "arch", 150);
		archField.setAlign(Alignment.RIGHT);
		g.setFields(new ListGridField("name", "Name", 190), new ListGridField("qtype", "type", 90), new ListGridField("slots", "slots", 70), archField, new ListGridField("state", "state", 60));

		ListGridRecord rs[] = new ListGridRecord[1];
		ListGridRecord record = new ListGridRecord();
		record.setAttribute("name", queue.getName());
		record.setAttribute("qtype", queue.getQtype());
		record.setAttribute("arch", queue.getArch());
		record.setAttribute("state", queue.getState());
		record.setAttribute("slots", queue.getSlots_Used() + "/" + queue.getSlots_Resv() + "/" + queue.getSlots_Total());
		rs[0] = record;
		g.setData(rs);

		return g;
	}

	boolean loaded = false;

	public void load()
	{
		if (loaded)
			return;
		loaded = true;
		StaticHolder.setStatusMessage("loading queue listing ...", 3);
		ApplicationCallBack<Qstat> callback = new ApplicationCallBack<Qstat>()
		{

			public void onFailureAfter(Throwable caught)
			{

				SC.warn(caught.getMessage(), StaticHolder.dumpB);
			}

			public void onSuccessAfter(Qstat result)
			{

				init(result);
			}

			public void execute()
			{
				QstatProxyAsync proxy = (QstatProxyAsync) GWT.create(QstatProxy.class);
				proxy.getQstat(this);
			}

		};
		callback.execute();

	}

	public void reload()
	{
		loaded = false;
		load();
	}

	
}
